import numpy as npimport plotly.graph_objects as goimport plotly.io as pio#-------------Base parameters#Define curve parametersperiod =50n_samples =100sim_duration = period*10amp =3x = np.arange(n_samples)*np.pi/period#Animation parametersframe_duration =50#milliseconds?#Define some groups of parameters here as dictionaries# This greatly clarifies later code# plotly takes arguments which are lists of dicts of lists of dicts... confusingdef frame_arguments(duration):return {"frame": {"duration": duration},"mode": "immediate","redraw": True,"fromcurrent": True,"transition": {"duration": duration, "easing": "linear"},"uirevision": True }#--------------Meat and potatoes#Create figure object containing one trace of the desired graph typefig = go.Figure( data=[go.Scatter3d( x = [], y = [], z = [], mode ="lines", name ="SineTest")])#Define the layout of that figure (size, axes ranges, etc.)fig.update_layout( template ="plotly_white", scene =dict( xaxis=dict(range=[0,2*np.pi], autorange=False), yaxis=dict(range=[-3,3], autorange=False), zaxis=dict(range=[0,2*np.pi], autorange=False)))#Now customize -- set the background to transparent to pair with themefig.update_layout(plot_bgcolor='rgba(0, 0, 0, 0)',paper_bgcolor='rgba(0, 0, 0, 0)')#Define all frames within the animationframes = [go.Frame(data=[go.Scatter3d( x=x, y=amp*np.sin(x+t*np.pi/period), z=x)], traces=[0], name=f"frame_{t}")for t inrange(1, sim_duration)]#Assign said frames to the figurefig.update(frames=frames)#Define the protocols for updating the figure# Here, a button which causes the figure to loop linearly through the framefig.update_layout( updatemenus = [ {"buttons": [ {"label" : "Play","method" : "animate", #Affects animation"args" : [None, frame_arguments(frame_duration)] }, {"label" : "Pause","method" : "animate",#To FutureJake: This is jank you can't just make a pause button by setting the frame duration to ten billion seconds [FIX]# To PastJake: Who's going to stop me?"args" : [None, frame_arguments(1000000000)] } ],#Position/display arguments for the buttons"y" : 0.5,"yanchor" : "bottom","xanchor" : "center","type" : "buttons" }, {"buttons": [ {"label" : "Lightmode","method" : "relayout", #Affects layout attributes"args" : ["template", pio.templates["plotly_white"]] }, {"label" : "Darkmode","method" : "relayout", #Affects layout attributes"args" : ["template", pio.templates["plotly_dark"]] } ],"y" : 0.4,"yanchor" : "top","xanchor" : "center","direction" : "down","type" : "dropdown" } ]) #Finally, render the figurefig.show()
Code
import plotly.graph_objects as goimport numpy as np#Curve parametersperiod =50n_samples =100sim_time = period*10x = np.arange(n_samples)*np.pi/periodfig = go.Figure(go.Scatter(x=x, y=np.sin(x), mode='lines', name='Testing Points'))fig.update_layout(title='Animation Test', title_x=0.5, width=600, height=600, xaxis_title='time', yaxis_title='E', yaxis_range=(-1.5, 1.5), xaxis_range=(0,2*np.pi),#defines the play button and animation settings updatemenus=[dict(buttons = [dict( args = [None, {"frame": {"duration": period, "redraw": False},"fromcurrent": True, "transition": {"duration": 0}}], label ="Play", method ="animate")],type='buttons', showactive=False, xanchor='right', yanchor='top')])frames= [go.Frame(data=[go.Scatter(x=x, y=np.sin(x+t*np.pi/period))]) for t inrange(1, sim_time)]fig.update(frames=frames)fig.show()